<template>
  <div class="knowledge-chat-container">
    <!-- 主内容区域 - 改为Flex布局 -->
    <div class="main-layout">
      <!-- 左侧聊天区域（宽度减小） -->
      <el-card class="chat-container">
        <template #header>
          <div class="chat-header">
            <span>知识库问答对话</span>
            <div class="header-actions">
              <el-button size="small" @click="showKnowledgeDialog = true">
                知识库选择
              </el-button>
              <el-button size="small" @click="clearChat" :disabled="messages.length === 0">
                清空对话
              </el-button>
            </div>
          </div>
        </template>

        <div ref="chatWindow" class="chat-window">
          <!-- 现有聊天内容保持不变 -->
          <div v-if="messages.length === 0" class="empty-chat">
            <el-empty description="暂无对话记录" />
          </div>

          <div v-else class="messages-list">
            <!-- 用户消息 -->
            <div v-for="(message, index) in messages" :key="index" class="message-item"
              :class="{ 'user-message-item': message.type === 'user' }">
              <div :class="['message-bubble', message.type]">
                <div class="message-avatar">
                  <el-avatar :size="32">
                    {{ message.type === 'user' ? '用' : 'AI' }}
                  </el-avatar>
                </div>
                <div class="message-content">
                  <div v-if="message.type === 'ai'" class="ai-message">
                    <div v-html="message.renderedContent" class="markdown-content"></div>

                    <!-- 图片展示区域 -->
                    <div v-if="message.images && message.images.length" class="image-gallery">
                      <div v-for="image in message.images" :key="image.index" class="image-item">
                        <div class="image-description">{{ image.description }}</div>
                        <el-image :src="image.url" :alt="image.description" :preview-src-list="[image.url]"
                          fit="contain" class="content-image" :style="{ maxWidth: getImageSize(image.url) }">
                          <template #error>
                            <div class="image-error">
                              <el-icon>
                                <Picture />
                              </el-icon>
                              <span>图片加载失败</span>
                            </div>
                          </template>
                        </el-image>
                      </div>
                    </div>
                  </div>

                  <div v-else class="user-message">
                    {{ message.content }}
                  </div>
                </div>
              </div>
            </div>

            <!-- 流式响应中的消息 -->
            <div v-if="isStreaming" class="message-item">
              <div class="message-bubble ai">
                <div class="message-avatar">
                  <el-avatar :size="32">AI</el-avatar>
                </div>
                <div class="message-content">
                  <div v-html="renderedStreamingContent" class="markdown-content"></div>
                  <div v-if="currentImages.length" class="image-gallery">
                    <div v-for="image in currentImages" :key="image.index" class="image-item">
                      <div class="image-description">{{ image.description }}</div>
                      <el-image :src="image.url" :alt="image.description" :preview-src-list="[image.url]" fit="contain"
                        class="content-image" :style="{ maxWidth: getImageSize(image.url) }">
                        <template #error>
                          <div class="image-error">
                            <el-icon>
                              <Picture />
                            </el-icon>
                            <span>图片加载失败</span>
                          </div>
                        </template>
                      </el-image>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 底部输入区域 -->
        <div class="input-area">
          <el-input v-model="userInput" type="textarea" :rows="3" placeholder="请输入您的问题，按Enter发送（Shift+Enter换行）"
            :disabled="isStreaming || selectedKnowbaseIds.length === 0" @keydown.enter="handleKeydown" />

          <div class="input-actions">
            <el-tooltip content="请至少选择一个知识库" placement="top">
              <span>
                <el-button type="primary" @click="sendMessage"
                  :disabled="isStreaming || selectedKnowbaseIds.length === 0 || !userInput.trim()"
                  :loading="isStreaming">
                  发送
                </el-button>
              </span>
            </el-tooltip>

            <el-button @click="clearInput">
              清空
            </el-button>
          </div>
        </div>
      </el-card>

      <!-- 右侧知识图谱区域 -->
      <el-card v-if="currentGraphData" class="graph-container">
        <template #header>
          <div class="graph-header">
            <span>相关知识图谱</span>
            <el-tooltip content="刷新图谱" placement="top">
              <el-button size="small" @click="refreshGraph" :loading="graphLoading">
                <el-icon>
                  <Refresh />
                </el-icon>
              </el-button>
            </el-tooltip>
          </div>
        </template>

        <div class="graph-content">
          <!-- 知识图谱可视化容器 -->
          <div class="graph-canvas">
            <!-- 这里将渲染知识图谱 -->
            <div v-if="graphLoading" class="graph-loading">
              <el-icon class="loading-icon">
                <Loading />
              </el-icon>
              <span>图谱加载中...</span>
            </div>
            <div v-else-if="!graphNodes.length" class="graph-empty">
              <el-empty description="暂无图谱数据" />
            </div>
            <div v-else ref="graphCanvas" class="knowledge-graph"></div>
          </div>

          <!-- 放大按钮 - 固定在右下角 -->
          <el-button v-if="graphNodes.length > 0" class="zoom-button" type="primary" size="small"
            @click="showZoomDialog = true">
            <el-icon>
              <ZoomIn />
            </el-icon>
            放大查看
          </el-button>
        </div>
      </el-card>
    </div>

    <!-- 知识库选择弹窗（保持不变） -->
    <el-dialog v-model="showKnowledgeDialog" title="选择知识库" width="60%" :close-on-click-modal="false">
      <div class="knowledge-dialog-content">
        <div class="knowledge-list">
          <el-table :data="knowledgeBases" style="width: 100%" height="400px">
            <el-table-column width="50">
              <template #default="scope">
                <el-checkbox-group v-model="selectedKnowbaseIds">
                  <el-checkbox :label="scope.row.know_base_id" :value="scope.row.know_base_id" />
                </el-checkbox-group>
              </template>
            </el-table-column>
            <el-table-column prop="know_base_name" label="知识库名称" />
            <el-table-column prop="create_date" label="创建日期" width="180">
              <template #default="scope">
                {{ formatDate(scope.row.create_date) }}
              </template>
            </el-table-column>
          </el-table>
        </div>

        <div class="pagination">
          <el-pagination background layout="prev, pager, next" :total="totalKnowledgeBases" :page-size="pageSize"
            :current-page="currentPage" @current-change="handlePageChange" />
        </div>
      </div>

      <template #footer>
        <el-button @click="showKnowledgeDialog = false">取消</el-button>
        <el-button type="primary" @click="confirmKnowledgeSelection">确定</el-button>
      </template>
    </el-dialog>

    <!-- 知识图谱放大弹框 -->
    <el-dialog v-model="showZoomDialog" title="知识图谱放大视图" width="90%" class="zoom-graph-dialog"
      :close-on-click-modal="false">
      <div class="zoom-graph-container">
        <div ref="zoomGraphCanvas" class="zoom-knowledge-graph"></div>
      </div>
      <template #footer>
        <el-button @click="handleCloseZoomDialog">关闭</el-button>
        <el-button type="primary" @click="exportGraphImage">导出图片</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, nextTick, computed, watch, onMounted, onUnmounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Picture, ZoomIn, Refresh, Loading } from '@element-plus/icons-vue';
import { ragQueryStream } from '@/services/rag';
import { renderMarkdown } from '@/utils/markdownRender';
import { getKnowledgeBases } from '@/services/rag';
// 引入ECharts用于知识图谱可视化
import * as echarts from 'echarts';

// 现有代码保持不变
const selectedKnowbaseIds = ref([]);
const userInput = ref('');
const messages = ref([]);
const isStreaming = ref(false);
const streamingContent = ref('');
const chatWindow = ref(null);
const showKnowledgeDialog = ref(false);
const knowledgeBases = ref([]);
const totalKnowledgeBases = ref(0);
const pageSize = ref(10);
const currentPage = ref(1);
const currentImages = ref([]);
const streamingBuffer = ref('');

const resizeObserver = ref(null);

// 新增：知识图谱相关状态
const currentGraphData = ref(null); // 当前图谱数据
const graphNodes = ref([]); // 图谱节点
const graphLinks = ref([]); // 图谱关系
const showZoomDialog = ref(false); // 放大弹框控制
const graphLoading = ref(false); // 图谱加载状态
const graphCanvas = ref(null); // 图谱DOM引用
const zoomGraphCanvas = ref(null); // 放大图谱DOM引用
let graphChart = null; // ECharts实例
let zoomGraphChart = null; // 放大图ECharts实例

// 计算属性保持不变
const renderedStreamingContent = computed(() => {
  return renderMarkdown(streamingContent.value);
});

const handleCloseZoomDialog = () => {
  showZoomDialog.value = false;
};

// 方法：获取图片尺寸
const getImageSize = (url) => {
  if (url.includes('table')) {
    return '100%';
  }
  return '400px';
};

// 方法：格式化日期
const formatDate = (dateString) => {
  const date = new Date(dateString);
  return date.toLocaleDateString();
};

// 方法：处理分页变化
const handlePageChange = (page) => {
  currentPage.value = page;
  fetchKnowledgeBases();
};

// 方法：获取知识库列表
const fetchKnowledgeBases = async () => {
  try {
    const response = await getKnowledgeBases({
      page: currentPage.value,
      page_size: pageSize.value
    });

    knowledgeBases.value = response.list || [];
    totalKnowledgeBases.value = response.total_items || 0;
  } catch (error) {
    console.error('获取知识库列表失败:', error);
    ElMessage.error('获取知识库列表失败');
  }
};

// 方法：确认知识库选择
const confirmKnowledgeSelection = () => {
  showKnowledgeDialog.value = false;
};


// 方法：发送消息（修改：添加图谱数据处理）
const sendMessage = async () => {
  if (!userInput.value.trim() || selectedKnowbaseIds.value.length === 0 || isStreaming.value) {
    return;
  }

  const question = userInput.value.trim();

  // 添加用户消息
  messages.value.push({
    type: 'user',
    content: question,
  });

  userInput.value = '';
  isStreaming.value = true;
  streamingContent.value = '';
  streamingBuffer.value = '';
  currentImages.value = [];
  currentGraphData.value = null; // 重置图谱数据

  try {
    await ragQueryStream(
      {
        knowledge_bases: selectedKnowbaseIds.value,
        question: question
      },
      // 数据接收回调（修改：添加图谱数据处理）
      (data) => {
        if (data.text && data.type === 'thinking') {
          streamingContent.value = streamingContent.value + data.text + '\n';
        } else if (data.text) {
          streamingContent.value += data.text;
          scrollToBottom(); // 每次更新后滚动
        } else if (data.images && data.type === 'images_info') {
          currentImages.value = data.images;
          scrollToBottom(); // 每次更新后滚动
        } else if (data.graph_data) {
          // 处理知识图谱数据
          currentGraphData.value = data.graph_data;
          processGraphData(data.graph_data);
        } else if (data.error) {
          ElMessage.error(`服务器错误: ${data.error}`);
        }
      },
      // 流完成回调
      () => {
        if (streamingContent.value || currentImages.value.length) {
          const newMessage = {
            type: 'ai',
            content: streamingContent.value,
            images: [...currentImages.value],
            graph: currentGraphData.value,
            renderedContent: renderMarkdown(streamingContent.value)
          };

          messages.value.push(newMessage);
          scrollToBottom();
        }
        resetStreaming();
      },
      // 错误回调
      (error) => {
        console.error('流式请求错误:', error);
        ElMessage.error('请求失败: ' + error.message);
        resetStreaming();
      }
    );

  } catch (error) {
    console.error('发送消息失败:', error);
    ElMessage.error('发送失败，请检查网络连接');
    resetStreaming();
  }
};

// 新增：处理知识图谱数据
const processGraphData = (graphData) => {
  if (!graphData) return;
  graphLoading.value = true;
  try {
    // 解析图谱数据
    graphNodes.value = (graphData.nodes || []).map(node => ({
      name: node.name || '未知节点',
      type: node.type || 'default',// 确保有默认类型
      id: node.id || '',
    }));
    // graphNodes.value = graphData.nodes || [];
    graphLinks.value = (graphData.links || []).map(link => ({
      source: link.source || '',
      target: link.target || '',
      relation: link.relation || '关系',
      // 其他字段...
    }));
    // 渲染图谱
    renderKnowledgeGraph();
  } catch (error) {
    console.error('处理图谱数据失败:', error);
    ElMessage.error('图谱渲染失败');
  } finally {
    graphLoading.value = false;
  }
};

// 新增：渲染知识图谱
// 修改后的 renderKnowledgeGraph 方法
const renderKnowledgeGraph = () => {
  if (!graphNodes.value.length) return;
  nextTick(() => {
    if (!graphCanvas.value) return;
    // 检查容器是否可见
    const style = window.getComputedStyle(graphCanvas.value);
    if (style.display === 'none') {
      console.warn('图谱容器不可见，延迟渲染');
      setTimeout(renderKnowledgeGraph, 100);
      return;
    }
    // 检查DOM尺寸
    if (graphCanvas.value.clientWidth === 0 || graphCanvas.value.clientHeight === 0) {
      console.warn('图谱容器尺寸为0，延迟渲染');
      // 创建ResizeObserver监听尺寸变化
      if (!resizeObserver.value) {
        resizeObserver.value = new ResizeObserver(entries => {
          for (let entry of entries) {
            if (entry.contentRect.width > 0 && entry.contentRect.height > 0) {
              renderKnowledgeGraph();
              resizeObserver.value.disconnect();
              resizeObserver.value = null;
              break;
            }
          }
        });
        resizeObserver.value.observe(graphCanvas.value);
      }
      return;
    }

    // 销毁旧实例
    if (graphChart) {
      graphChart.dispose();
    }

    // 初始化ECharts实例
    graphChart = echarts.init(graphCanvas.value);

    // 获取唯一的节点类型用于图例
    const nodeTypes = [...new Set(graphNodes.value.map(node => node.type))].filter(Boolean);
    // 创建反向映射用于显示中文
    const option = {
      tooltip: {
        formatter: function (params) {
          if (params.dataType === 'node') {
            // 使用节点的originalType属性（中文）
            return `${params.data.name}<br/>类型: ${params.data.type || '未知'}`;
          } else {
            return `关系: ${params.data.relation || '未知'}`;
          }
        }
      },
      visualMap: {
        show: true,
        dimension: 'dataType', // 控制节点类型的映射
        pieces: nodeTypes.map(type => ({
          value: type,
          label: type,
          color: getNodeColor(type)
        })),
        orient: 'right',
        top: 'middle',
        left: 'auto'
      },
      series: [{
        type: 'graph',
        name: '知识图谱', // 添加系列名称
        layout: 'force',
        symbolSize: 50,
        // 修复：使用新的API替代已弃用的focusNodeAdjacency
        emphasis: {
          focus: 'adjacency', // ✅ 替代 focusNodeAdjacency: true
          scale: true,
          lineStyle: {
            width: 3
          }
        },
        roam: true,
        edgeSymbol: ['circle', 'arrow'],
        edgeSymbolSize: [4, 10],
        edgeLabel: {
          show: true,
          formatter: function (params) {
            return params.data.relation || ''; // 使用实际的relation字段
          }
        },
        force: {
          repulsion: 1000,
          edgeLength: 200
        },
        data: graphNodes.value.map(node => ({
          ...node,
          value: node.type,
          itemStyle: {
            color: getNodeColor(node.type)
          }
        })),
        links: graphLinks.value.map(link => ({
          ...link,
          lineStyle: {
            color: '#aaa',
            width: 2
          }
        })),
        label: {
          show: true,
          position: 'inside',
          formatter: '{b}',
          fontSize: 12
        },
        lineStyle: {
          color: 'source',
          curveness: 0.3
        },
        emphasis: {
          focus: 'adjacency',
          scale: true
        },
        // 告诉 ECharts 节点的颜色由哪个字段决定
        encode: {
          tooltip: ['name', 'type'],
          itemName: 'name' // 指定节点名称字段
        }
      }]
    };

    try {
      graphChart.setOption(option);
      window.addEventListener('resize', () => {
        if (graphChart && !graphChart.isDisposed()) {
          graphChart.resize();
        }
      });
    } catch (error) {
      console.error('渲染知识图谱失败:', error);
      ElMessage.error('知识图谱渲染失败');
    }
  });
};

// 新增：渲染放大图谱
// 修改后的 renderZoomGraph 方法
const renderZoomGraph = () => {
  if (!graphNodes.value.length) return;
  nextTick(() => {
    if (!zoomGraphCanvas.value) {
      console.error('放大图谱容器未找到');
      return;
    }
    // 检查DOM尺寸
    if (zoomGraphCanvas.value.clientWidth === 0 || zoomGraphCanvas.value.clientHeight === 0) {
      console.warn('放大图谱容器尺寸为0，延迟渲染');
      setTimeout(renderZoomGraph, 100);
      return;
    }
    // 销毁旧实例
    if (zoomGraphChart) {
      zoomGraphChart.dispose();
    }
    // 初始化放大图实例
    zoomGraphChart = echarts.init(zoomGraphCanvas.value);
    // 获取唯一的节点类型
    const nodeTypes = [...new Set(graphNodes.value.map(node => node.type))].filter(Boolean);
    const option = {
      tooltip: {
        formatter: function (params) {
          if (params.dataType === 'node') {
            // 使用节点的originalType属性（中文）
            return `${params.data.name}<br/>类型: ${params.data.type || '未知'}`;
          } else {
            return `关系: ${params.data.relation || '未知'}`;
          }
        }
      },
      // 使用 visualMap 替代 legend 进行类型映射（推荐）
      visualMap: {
        show: true,
        dimension: 'dataType', // 控制节点类型的映射
        pieces: nodeTypes.map(type => ({
          value: type,
          label: type,
          color: getNodeColor(type)
        })),
        orient: 'right',
        top: 'middle',
        left: 'auto'
      },
      series: [{
        type: 'graph',
        name: '知识图谱放大视图',
        layout: 'force',
        symbolSize: 80,
        // 修复：使用新的API
        emphasis: {
          focus: 'adjacency', // ✅ 替代 focusNodeAdjacency: true
          scale: true,
          lineStyle: {
            width: 4
          }
        },
        roam: true,
        edgeSymbol: ['circle', 'arrow'],
        edgeSymbolSize: [4, 10],
        edgeLabel: {
          show: true,
          formatter: function (params) {
            return params.data.relation || ''; // 使用实际的relation字段
          },
          fontSize: 14
        },
        force: {
          repulsion: 1500,
          edgeLength: 300
        },
        data: graphNodes.value.map(node => ({
          ...node,
          // 关键：将 type 映射为 value，用于 visualMap 匹配
          value: node.type,
          itemStyle: {
            color: getNodeColor(node.type)
          }
        })),
        links: graphLinks.value.map(link => ({
          ...link,
          lineStyle: {
            color: '#aaa',
            width: 3
          }
        })),
        label: {
          show: true,
          position: 'inside',
          formatter: '{b}',
          fontSize: 16
        },
        lineStyle: {
          color: 'source',
          curveness: 0.3
        },
        emphasis: {
          focus: 'adjacency',
          scale: true
        },
        // 告诉 ECharts 节点的颜色由哪个字段决定
        encode: {
          tooltip: ['name', 'type'],
          itemName: 'name' // 指定节点名称字段
        }
      }]
    };

    try {
      zoomGraphChart.setOption(option);
      // 自适应大小
      window.addEventListener('resize', () => {
        if (zoomGraphChart && !zoomGraphChart.isDisposed()) {
          zoomGraphChart.resize();
        }
      });
    } catch (error) {
      console.error('渲染放大图谱失败:', error);
      ElMessage.error('放大图谱渲染失败');
    }
    // 自适应大小
    window.addEventListener('resize', () => {
      if (zoomGraphChart && !zoomGraphChart.isDisposed()) {
        zoomGraphChart.resize();
      }
    });
  });
};

// 新增：获取节点颜色
const getNodeColor = (nodeType) => {
  const colorMap = {
    '现象': '#FF6B6B',
    '故障': '#4ECDC4',
    '问题': '#45B7D1',
    '原因': '#96CEB4',
    '解决方案': '#FECA57',
    '默认': '#5F7D95'
  };
  return colorMap[nodeType] || colorMap['default'];
};

// 新增：刷新图谱
const refreshGraph = () => {
  if (currentGraphData.value) {
    processGraphData(currentGraphData.value);
  }
};

// 新增：导出图谱图片
const exportGraphImage = () => {
  console.log('导出图片按钮被点击');
  if (!zoomGraphChart) {
    ElMessage.warning('图表尚未加载完成，请稍后再试');
    return;
  }

  try {
    console.log('获取图表数据URL');
    const imageUrl = zoomGraphChart.getDataURL({
      type: 'png',
      pixelRatio: 2,
      backgroundColor: '#fff'
    });
    console.log('创建下载链接');

    const link = document.createElement('a');
    link.download = `knowledge-graph-${new Date().format('YYYYMMDD-HHmmss')}.png`;
    link.href = imageUrl;
    document.body.appendChild(link); // 必须添加到DOM中
    link.click();
    // 使用后移除
    document.body.removeChild(link);
  } catch (error) {
    console.error('导出图片失败:', error);
    ElMessage.error('导出失败: ' + error.message);
  }
};

// 监听放大弹框显示状态
watch(showZoomDialog, (newVal) => {
  if (newVal) {
    // 添加加载提示
    const loading = ElMessage.info({
      message: '正在加载放大视图...',
      duration: 0
    });

    nextTick(() => {
      console.log('开始渲染放大图谱');
      renderZoomGraph();

      // 延迟关闭加载提示
      setTimeout(() => {
        loading.close();
      }, 1000);
    });
  } else {
    console.log('放大弹框关闭');
    // 清理图表实例
    if (zoomGraphChart) {
      console.log('清理放大图谱实例');
      zoomGraphChart.dispose();
      zoomGraphChart = null;
    }
  }
});


const handleKeydown = (event) => {
  if (event.shiftKey) return;
  event.preventDefault();
  sendMessage();
};

const clearInput = () => {
  userInput.value = '';
};

const clearChat = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有对话记录吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });

    messages.value = [];
    currentGraphData.value = null;
    graphNodes.value = [];
    graphLinks.value = [];
  } catch {
    // 用户取消
  }
};

// 修复滚动问题
const scrollToBottom = () => {
  nextTick(() => {
    if (chatWindow.value) {
      chatWindow.value.scrollTop = chatWindow.value.scrollHeight;

      // 添加额外检查，确保滚动位置正确
      const checkScroll = () => {
        const scrollDiff = chatWindow.value.scrollHeight -
          (chatWindow.value.scrollTop + chatWindow.value.clientHeight);

        if (scrollDiff > 10) { // 如果还有10px以上的内容不可见
          chatWindow.value.scrollTop = chatWindow.value.scrollHeight;
          setTimeout(checkScroll, 50); // 再次检查
        }
      };

      setTimeout(checkScroll, 100);
    }
  });
};

const resetStreaming = () => {
  isStreaming.value = false;
  streamingContent.value = '';
  currentImages.value = [];
  streamingBuffer.value = '';
};

// 组件挂载
onMounted(() => {
  fetchKnowledgeBases();
  // 确保容器可见
  if (graphCanvas.value) {
    const style = window.getComputedStyle(graphCanvas.value);
    if (style.display === 'none') {
      console.warn('图谱容器不可见，延迟渲染');
    }
  }
});

// 组件卸载时清理
onUnmounted(() => {
  if (graphChart) {
    graphChart.dispose();
  }
  if (zoomGraphChart) {
    zoomGraphChart.dispose();
  }

  // 清理ResizeObserver
  if (resizeObserver.value && typeof resizeObserver.value.disconnect === 'function') {
    resizeObserver.value.disconnect();
  }
});
</script>

<style scoped>
/* 主布局样式 */
.knowledge-chat-container {
  padding: 20px;
  height: calc(100vh - 100px);
}

.main-layout {
  display: flex;
  gap: 20px;
  height: 100%;
}

/* 左侧聊天区域样式（宽度减小） */
.chat-container {
  flex: 0 0 65%;
  /* 宽度调整为65% */
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* 防止内容溢出 */
}

/* 右侧知识图谱区域样式 */
.graph-container {
  flex: 0 0 35%;
  /* 宽度35% */
  display: flex;
  flex-direction: column;
  position: relative;
}

.graph-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.graph-content {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.graph-canvas {
  flex: 1;
  min-height: 400px;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  background: #fafafa;
}

.knowledge-graph {
  width: 100%;
  height: 100%;
  min-width: 300px;
  /* 添加最小宽度 */
  min-height: 400px;
  /* 添加最小高度 */
}

/* 图谱加载和空状态样式 */
.graph-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #666;
}

.loading-icon {
  font-size: 24px;
  margin-bottom: 10px;
  animation: rotate 2s linear infinite;
}

.graph-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

/* 放大按钮样式 */
.zoom-button {
  position: absolute;
  bottom: 15px;
  right: 15px;
  z-index: 10;
}

/* 放大弹框样式 */
.zoom-graph-container {
  height: 65vh;
}

.zoom-knowledge-graph {
  width: 100%;
  height: 100%;
  min-width: 500px;
  /* 放大视图最小宽度 */
  min-height: 600px;
  /* 放大视图最小高度 */
}

/* 现有聊天样式保持不变 */
.chat-window {
  flex: 1;
  overflow-y: auto;
  /* 确保滚动条可见 */
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  max-height: 52vh;
  /* 限制最大高度 */
}

/* 添加滚动条样式 */
.chat-window::-webkit-scrollbar {
  width: 8px;
}

.chat-window::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.chat-window::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.chat-window::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.empty-chat {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.messages-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 300px;
  /* 确保最小高度 */
}

.message-item {
  display: flex;
}

.message-bubble {
  display: flex;
  gap: 12px;
  max-width: 100%;
}

.message-bubble.user {
  flex-direction: row-reverse;
}

.message-content {
  flex: 1;
  max-width: calc(100% - 44px);
}

.ai-message,
.user-message {
  background: #f5f7fa;
  padding: 12px 16px;
  border-radius: 8px;
  max-width: 100%;
  word-break: break-word;
}

.user-message-item {
  justify-content: flex-end;
}

.user-message {
  background: #e1f5fe;
}

.input-area {
  border-top: 1px solid #e0e0e0;
  padding-top: 16px;
}

.input-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 12px;
}

/* 动画 */
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .main-layout {
    flex-direction: column;
  }

  .chat-container,
  .graph-container {
    flex: 1;
    width: 100%;
  }

  .graph-container {
    margin-top: 20px;
  }
}
</style>

<!-- 全局样式保持不变 -->
<style>
/* 现有全局样式 */
</style>